Barcode Xpress can be used as an ActiveX control in development environments that provide container support like Visual Basic or Visual C++. In this case, the BarcodeXpress control is placed on a form or dialog box.
You can also import BarcodeXpress as a COM object in development environments like Visual C++. In this case, BarcodeXpress is not restricted to a dialog box and it does not require container support. The following discussion assumes that your development environment is Visual C++.
Starting with version 5 of Visual C++, Microsoft has provided support for a new #import compiler directive that enables developers to import components directly as native COM objects, by-passing the ActiveX trappings. The following is a quote from a brief section of the Fourth Edition of Inside Visual C++ (Microsoft Press): "The #import directive is the future of COM programming. With each new version of Visual C++, you’ll see COM features moving into the compiler…"
How to use Barcode Xpress as an Imported COM Object in Visual C++.
References made to files in the Visual C++ sample, ReadBarcodeFromDIB, and pertinent statements are shown in boldface.
|
1. #importing a control into Visual C++
Importing a control via the #import directive is a simple process. The #import directive line can be added to the Stdafx.h file to provide the appropriate functionality to all source files in the project. The following example shows the #import directive used in the Stdafx.h file from the ReadBarcodeFromDIB project:
C++ ReadBarcodeFromDIB Sample Project | Copy Code |
---|---|
// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently #if !defined(AFX_STDAFX_H__73AF9569_D12A_49D1_82D7_9662053EE69A__INCLUDED_) #define AFX_STDAFX_H__73AF9569_D12A_49D1_82D7_9662053EE69A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #import "Accusoft.ImagXpress11.ActiveX.dll" #import "Accusoft.BarcodeXpress9.ActiveX.dll" //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__73AF9569_D12A_49D1_82D7_9662053EE69A__INCLUDED_) |
The #import directive simply points to the BarcodeXpress control. When the BarcodeXpress control is imported with the #import directive, the compiler produces 2 files – a .tli and a .tlh file – that together create the necessary COM wrapper for the control’s properties and methods. Since the directive is in your stdafx.h file, the wrappers are immediately available to your other modules. The wrapper code defines COM smart pointers to your .IDL-defined interfaces. To use this COM object, you simply create an instance of the interface you want and then call methods directly by using this instance pointer.
2. Define a pointer to the COM object
After the #import directive is added, a pointer to the BarcodeXpress COM object must be defined. In the ReadBarcodeFromDIB project, the pointer is called and it is implemented in the ReadBarcodeFromDIBDlg.h file as follows:
C++ example to define a pointer to the COM object | Copy Code |
---|---|
using namespace AccusoftBarcodeXpress9; #include "..\Include\BarcodeXpress9_Events.h" ... class CReadBarcodeFromDIBDlg : public CDialog { private: ... //ImagXpress pointers CImagXpress* m_ppCImagXpress; IImagXpressPtr m_pImagXpress; CBarcodeXpress* m_ppIBarcodeXpress; IBarcodeXpressPtr m_pBarcodeXpress; ... |
3. Initialize COM
The COM library must be initialized before COM functions can be called and it must be closed before the program exits. This is illustrated in the ReadBarcodeFromDIB.cpp file as follows:
C++ example to initialize and close COM library | Copy Code |
---|---|
///////////////////////////////////////////////////////////////////////////// // CReadBarcodeFromDIBApp initialization BOOL CReadBarcodeFromDIBApp::InitInstance() { // Initialize the COM library on the current apartment and identify // the currency model as single-thread apartment (STA). Applications // must initialize the COM // library before they can call COM library functions other than // CoGetMalloc and memory allocation functions. HRESULT hRes = CoInitialize(NULL); AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif CReadBarcodeFromDIBDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Closes the COM library on the current apartment, // unloads all DLLs loaded by apartment, // frees any other resources that the apartment maintains, and // forces all RPC connections on the apartment to close. CoUninitialize(); // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } |
4. Create the BarcodeXpress COM Object
To use BarcodeXpress, an instance of the BarcodeXpress COM object must be created. After the object is created, the object’s properties and methods can be used to create your scanning application. In the ReadBarcodeFromDIB project, the COM object is created in the ReadBarcodeFromDIBDlg.cpp file as follows:
Before you distribute applications that use the BarcodeXpress COM object, you need to edit the BarcodeXpress9_Open.cpp file and change the values passed to SetSolutionName, SetSolutionKey, and (if applicable) SetOEMLicenseKey. Obtain distribution codes from Accusoft. |
Example to create the BarcodeXpress object | Copy Code |
---|---|
///////////////////////////////////////////////////////////////////////////// // CReadBarcodeFromDIBDlg message handlers BOOL CReadBarcodeFromDIBDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here CWnd* pControl = NULL; pControl = GetDlgItem(Description); if (pControl) { pControl->SetWindowText(lpctstrDescription); } CRect oIXArea; oIXArea.left = 25; oIXArea.top = 215; oIXArea.right = 725; oIXArea.bottom = 636; // Create an ImagXpress Object m_ppCImagXpress = new CImagXpress(this, 1, (long) m_hWnd, oIXArea.left, oIXArea.top, oIXArea.Width(), oIXArea.Height()); m_pImagXpress = m_ppCImagXpress->pImagXpress; m_pImagXpress->PutCtlVisible(true); m_pImagXpress->AutoSize = ISIZE_BestFit; m_pImagXpress->ScrollBars = SB_Both; m_pImagXpress->MenuSetEnabled(Menu_Context,TOOL_None, true); // **Initialize Barcode. You must call BC_Open before // **creating the first BarcodeXpress COM object. You cannot distribute applications using // **BarcodeXpress COM objects without valid unlock codes. // Create a BarcodeXpress class object. The BarcodeXpress // class object automatically creates a Barcode Xpress // COM object. m_ppIBarcodeXpress = new CBarcodeXpress(this, 1); // The SetSolutionName, SetSolutionKey and possibly the SetOEMLicenseKey method must be // called to distribute the runtime. Note that the SolutionName, SolutionKey and // OEMLicenseKey values shown below are only examples. // //m_pBarcodeXpress->SetSolutionName("YourSolutionName"); //m_pBarcodeXpress->SetSolutionKey(12345, 12345, 12345, 12345); //m_pBarcodeXpress->SetOEMLicenseKey("1.0.AStringForOEMLicensingContactAccusoftSalesForMoreInformation..."); // //m_pImagXpress->SetSolutionName("YourSolutionName"); //m_pImagXpress->SetSolutionKey(12345, 12345, 12345, 12345); //m_pImagXpress->SetOEMLicenseKey("1.0.AStringForOEMLicensingContactAccusoftSalesForMoreInformation..."); // Get the pointer to the created BarcodeXpress Barcode COM object. // This is the pointer that you will use to access BarcodeXpress // Barcode properties and methods. m_pBarcodeXpress = m_ppIBarcodeXpress->pBarcodeXpress; // Close the BarcodeXpress Barcode initialization. // You must call this AFTER creating the first BarcodeXpress Barcode // COM object m_1D.SetCheck(BST_CHECKED); m_selection = 0; m_pImagXpress->FileName = "..\\..\\..\\..\\..\\..\\Common\\Images\\Barcode All Supported Types.tif"; return TRUE; // return TRUE unless you set the focus to a control } |
5. Use the BarcodeXpress COM Object to Set Properties and Call Methods
After an instance of the BarcodeXpress COM object is created, the object can be used to set BarcodeXpress properties and call BarcodeXpress methods. In the ReadBarcodeFromDIB project, this is illustrated in the OnDetectButton function shown below. This function is called when the user clicks the Recognized Barcode button.
C++ example to set BarcodeXpress properties and call methods | Copy Code |
---|---|
void CReadBarcodeFromDIBDlg::OnDetectButton() { // TODO: Add your control notification handler code here // Set barcode classification type based on selected radio button switch(m_selection) { case 0: { barcodetype = 0; //1D break; } case 1: { barcodetype = 524288; //Patch break; } case 2: { barcodetype = 0x4000000; //OneCode break; } case 3: { barcodetype = 2097152; //PDF break; } case 4: { barcodetype = 4194304; //DataMatrix break; } case 5: { barcodetype = 0x8000000; //Royal Post break; } case 6: { barcodetype = 1048576; //Post net break; } case 7: { barcodetype = 0x2000000; //QR break; } case 8: { barcodetype = 0x10000000; //Aus break; } } m_pBarcodeXpress->BarcodeType = barcodetype; m_pBarcodeXpress->ImageSource = BC_ImageSourceDIB; m_pBarcodeXpress->hDIB = m_pImagXpress->CopyDIB(); m_pBarcodeXpress->AnalyzeBC(0,0,0,0); int numBC = m_pBarcodeXpress->NumBarcodes; CString bcName; CString bcResult; CString result; CString strBarcodeInformation; if ((m_pBarcodeXpress->SSError == 0) & (m_pBarcodeXpress->NumBarcodes > 0)) { int i; for (i = 0 ; i < numBC ; i++) { m_pBarcodeXpress->GetBarcode(i); bcName = (BSTR) m_pBarcodeXpress->BarcodeCodeName; bcResult = (BSTR) m_pBarcodeXpress->BarcodeResult; strBarcodeInformation.FormatMessage(szBarcodeInfoFormat, i, bcResult, bcName); result += strBarcodeInformation; } MessageBox(result,"Barcode Result", MB_OK); } else { if (m_pBarcodeXpress->SSError != 0) { MessageBox("Error #" + m_pBarcodeXpress->SSError,"Error",MB_OK); } else { MessageBox("No barcodes found","Barcode Result", MB_OK); } } //Must Free the DIB passed into the Analyze method to avoid memory issues GlobalFree((HGLOBAL)m_pBarcodeXpress->hDIB); } |
6. Delete the BarcodeXpress COM Object
The BarcodeXpress COM object must be deleted when it is no longer needed. The object is usually deleted before the application exits. In the ReadBarcodeFromDIB project, the COM object is deleted as follows:
C++ example to delete the COM object | Copy Code |
---|---|
BOOL CReadBarcodeFromDIBDlg::DestroyWindow() { // TODO: Add your specialized code here and/or call the base class CDialog::OnDestroy(); if (m_pImagXpress) { m_pImagXpress = NULL; if (m_ppCImagXpress) { delete m_ppCImagXpress; } } if (m_pBarcodeXpress) { m_pBarcodeXpress = NULL; if (m_ppIBarcodeXpress) { delete m_ppIBarcodeXpress; } } return CDialog::DestroyWindow(); } |